package com.hq.zb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.hq.zb.dto.DeptDto;
import com.hq.zb.entity.CurrentUser;
import com.hq.zb.exception.BizException;
import com.hq.zb.exception.BizExceptionEnum;
import com.hq.zb.mapper.DeptMapper;
import com.hq.zb.model.Dept;
import com.hq.zb.model.Org;
import com.hq.zb.model.User;
import com.hq.zb.service.ICodeRulesHeaderService;
import com.hq.zb.service.IDeptService;
import com.hq.zb.service.IUserService;
import com.hq.zb.vo.DeptVo;
import com.hq.zb.vo.SelectCommVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门表 服务实现类
 * </p>
 *
 * @author huanghanrui
 * @since 2022-03-07
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {

    @Autowired
    private ICodeRulesHeaderService codeRulesHeaderService;

    @Autowired
    private IUserService userService;

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public void saveDept(DeptDto deptDto) {
        Dept dept = new Dept();
        BeanUtil.copyProperties(deptDto, dept);
        if (dept.getDeptLevel() == null) {
            //部门等级不允许为空
            throw new BizException(BizExceptionEnum.DATA_NOT_NULL, "部门等级必填.");
        }
        if (StringUtils.isBlank(dept.getDeptName())) {
            //部门编码不允许为空
            throw new BizException(BizExceptionEnum.DATA_NOT_NULL, "部门编码必填.");
        }
        if (dept.getDeptLevel() != 0L && StringUtils.isBlank(dept.getParentDept())) {
            //不是零级部门的的父部门编码不允许为空
            throw new BizException(BizExceptionEnum.DATA_NOT_NULL, "父部门编码必填.");
        } else {
            if (StringUtils.isNotBlank(dept.getParentDept())) {
                Wrapper<Dept> entityWrapper = new EntityWrapper<>();
                entityWrapper.eq("dept_code", dept.getParentDept());
                List<Dept> depts = this.selectList(entityWrapper);
                if (CollectionUtil.isEmpty(depts)) {
                    //父部门编码系统中不存在
                    throw new BizException(BizExceptionEnum.DATA_NOT_EXIST, "父部门编码在系统中不存在.");
                } else {
                    dept.setOrgCode(depts.get(0).getOrgCode());
                }
                if (StringUtils.isBlank(dept.getDeptCode())) {
                    //生成部门编码
                    String ruleName = depts.get(0).getParentDept() + "下级部门编码规则";
                    String code =  codeRulesHeaderService.getCode(dept.getParentDept(), ruleName, dept.getParentDept(), 3);
                    dept.setDeptCode(code);
                }
            }
        }
        //同一组织下部门名称不允许重复
        Wrapper<Dept> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("delete_flag", false);
        entityWrapper.eq("dept_name", dept.getDeptName());
        entityWrapper.eq("org_code", dept.getOrgCode());
        List<Dept> depts = this.selectList(entityWrapper);
        //验证是否存在改变父级部门
        if (dept.getDeptId() == null) {
            if (CollectionUtil.isNotEmpty(depts)) {
                throw new BizException(BizExceptionEnum.DATA_NOT_ONLY, "部门名称在系统中已存在.");
            }
            this.insert(dept);
        } else {
            if (CollectionUtil.isNotEmpty(depts)) {
                depts = depts.stream().filter(x-> dept.getDeptId() != x.getDeptId()).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(depts)) {
                    throw new BizException(BizExceptionEnum.DATA_NOT_ONLY, "部门名称在系统中已存在.");
                }
            }
            this.updateById(dept);
            //修改子部门编码
            if (!deptDto.getDeptCode().equals(dept.getDeptCode())) {
                //查询子部门统一批量修改
                Wrapper<Dept> wrapper = new EntityWrapper<>();
                wrapper.eq("delete_flag", false);
                wrapper.like("dept_code", deptDto.getDeptCode());
                List<Dept> deptList = this.selectList(wrapper);
                if (CollectionUtil.isNotEmpty(deptList)) {
                    for (Dept d : deptList) {
                        String deptCode = d.getDeptCode();
                        deptCode = deptCode.replace(deptDto.getDeptCode(), dept.getDeptCode());
                        d.setDeptCode(deptCode);
                        String parentDept = d.getParentDept();
                        parentDept = parentDept.replace(deptDto.getDeptCode(), dept.getDeptCode());
                        d.setParentDept(parentDept);
                    }
                    this.updateBatchById(depts);
                }
                //修改用户部门编码
                Wrapper<User> userWrapper = new EntityWrapper<>();
                userWrapper.like("dept_code", deptDto.getDeptCode());
                List<User> users = userService.selectList(userWrapper);
                if (CollectionUtil.isNotEmpty(users)) {
                    for (User user : users) {
                        String deptCode = user.getDeptCode();
                        deptCode.replace(deptDto.getDeptCode(), dept.getDeptCode());
                        user.setDeptCode(deptCode);
                    }
                    userService.updateBatchById(users);
                }
            }
        }
    }

    @Override
    public Page<DeptVo> listByPage(Page<DeptVo> page, Wrapper<DeptVo> wrapper) {
        page.setRecords(deptMapper.listByPage(page, wrapper));
        return page;
    }

    @Override
    public List<SelectCommVo> queryList(DeptDto deptDto, CurrentUser currentUser) {
        Wrapper<Dept> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq("delete_flag", false);
        if (StringUtils.isNotEmpty(currentUser.getOrgCode())) {
            entityWrapper.eq("org_code", currentUser.getOrgCode());
        }
        if (StringUtils.isNotEmpty(deptDto.getParentDept())) {
            entityWrapper.eq("parent_dept", deptDto.getParentDept());
        }
        List<Dept> depts = this.selectList(entityWrapper);
        List<SelectCommVo> selectCommVos = null;
        if (CollectionUtil.isNotEmpty(depts)) {
            List<Dept> menuTree = depts.stream().filter(x -> StringUtils.isBlank(x.getParentDept())).collect(Collectors.toList());
            List<Dept> deptList = depts.stream().filter(x -> StringUtils.isNotEmpty(x.getParentDept())).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(menuTree)) {
                selectCommVos = new ArrayList<>();
                for (Dept dept : menuTree) {
                    SelectCommVo selectCommVo = new SelectCommVo();
                    selectCommVo.setValue(dept.getDeptCode());
                    selectCommVo.setLabel(dept.getDeptName());
                    selectCommVo.setChildren(getChild(dept.getDeptCode(), deptList));
                    selectCommVos.add(selectCommVo);
                }
            }
        }
        return selectCommVos;
    }

    @Override
    public void deleteDept(List<Dept> depts) {
        if (CollectionUtil.isNotEmpty(depts)) {
            for (Dept dept : depts) {
                dept.setDeleteFlag(true);
                deptMapper.updateById(dept);
            }
        }
    }

    /**
     * 递归查找子菜单
     * @param deptCode
     * @param depts
     */
    private List<SelectCommVo> getChild(String deptCode, List<Dept> depts) {
        if (CollectionUtil.isNotEmpty(depts)) {
            List<Dept> deptList = depts.stream().filter(x -> StringUtils.isNotEmpty(x.getParentDept()) && x.getParentDept().equals(deptCode)).collect(Collectors.toList());
            List<Dept> deptList1 = depts.stream().filter(x -> StringUtils.isNotEmpty(x.getParentDept()) && !x.getParentDept().equals(deptCode)).collect(Collectors.toList());
            List<SelectCommVo> childList = null;
            if (CollectionUtil.isNotEmpty(deptList)) {
                childList = new ArrayList<>();
                for (Dept dept : deptList) {
                    if (StringUtils.isNotEmpty(dept.getParentDept())) {
                        if (dept.getParentDept().equals(deptCode)) {
                            SelectCommVo selectCommVo = new SelectCommVo();
                            selectCommVo.setValue(dept.getDeptCode());
                            selectCommVo.setLabel(dept.getDeptName());
                            childList.add(selectCommVo);
                            if (CollectionUtil.isNotEmpty(deptList1)) {
                                selectCommVo.setChildren(getChild(dept.getDeptCode(), deptList1));
                            }
                        }
                    }
                }
            }
            return childList;
        }
        return null;
    }
}
